#include "StdAfx.h"
#include "HPAscySocket.h"
#include "Mswsock.h"
#include "HPPer_IO.h"
#include "HPPer_socket.h"
#include "HPErrorHandling.h"
#pragma comment(lib,"ws2_32.lib")
volatile const LPFN_ACCEPTEX  HPAscySocket::m_lpfnAcceptEx = NULL;
volatile const LPFN_DISCONNECTEX HPAscySocket::lpfnDisconnectEx = NULL;
void HPAscySocket::socketServerStart()
{
	WSADATA wData;
	if (0 != WSAStartup(MAKEWORD(2,2),&wData))
	{
		int errorCode = GetLastError();
		pObjErrorHanding->ErrorHandlingAndLogging(errorCode,0);
	}
}
void HPAscySocket::createSocketByTranslateService(int af, int type, int protocol, SOCKET socketCreated)
{
	if (INVALID_SOCKET == (socketCreated = socket(af,type,protocol)))
	{
		int errorCode = GetLastError();
		pObjErrorHanding->ErrorHandlingAndLogging(errorCode,0);
	}
}
void HPAscySocket::bindIPWithPortAndProtolOnCreatedSocket(SOCKET socketCreated, short family, unsigned int port)
{
	sockaddr_in socketIpAndPort;
	socketIpAndPort.sin_family = family;
	socketIpAndPort.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	socketIpAndPort.sin_port = htons(port);
	if (SOCKET_ERROR == bind(socketCreated, (SOCKADDR*)&socketIpAndPort, sizeof(socketIpAndPort)))
	{
		int errorCode = GetLastError();
		if (errorCode != WSA_IO_PENDING)
		{
			pObjErrorHanding->ErrorHandlingAndLogging(errorCode,0);
		}
	}
}
void HPAscySocket::registerSocketAsListenSocket(SOCKET socketBound, unsigned int listenAmounts)
{
	if (listen(socketBound, listenAmounts) == SOCKET_ERROR)
	{
		int errorCode = GetLastError();
		if (errorCode != WSA_IO_PENDING)
		{
			pObjErrorHanding->ErrorHandlingAndLogging(errorCode,0);
		}
	}
}
void HPAscySocket::m_AcceptEx(SOCKET listenSocket, HPPer_IO *perIO)
{
	perIO->m_OpType = ACCEPT_POSTED;
	
	if (false == m_lpfnAcceptEx(listenSocket, perIO->m_hSocket, perIO->m_aBuffer, NULL, sizeof(SOCKADDR_IN)+16,
		sizeof(SOCKADDR_IN)+16, &dwBytes, &perIO->m_Overlapped))
	{
		int errorCode = GetLastError();
		if (errorCode != WSA_IO_PENDING)
		{
			pObjErrorHanding->ErrorHandlingAndLogging(errorCode,0);
		}
	}
}
void HPAscySocket::sendData(HPPer_IO *perIO)
{
	perIO->m_OpType = SEND_POSTED;
	
	if (0 != WSASend(perIO->m_hSocket,perIO->m_aWsaBuf,perIO->m_NumOfSendBuf,&dwBytes,mFlag,&perIO->m_Overlapped,NULL));
	{
		int errorCode = GetLastError();
		if (errorCode != WSA_IO_PENDING)
		{
			pObjErrorHanding->ErrorHandlingAndLogging(errorCode,0);
		}
	}
}
void HPAscySocket::receiveData(HPPer_IO *perIO)
{
	perIO->m_OpType = RECV_POSTED;
	if (0 != WSARecv(perIO->m_hSocket,perIO->m_aWsaBuf,perIO->m_NumOfSendBuf,&dwBytes,&mFlag,&perIO->m_Overlapped,NULL))
	{
		int errorCode = GetLastError();
		if (errorCode != WSA_IO_PENDING)
		{
			pObjErrorHanding->ErrorHandlingAndLogging(errorCode,0);
		}
	}
}
void HPAscySocket::disconnectSocket(HPPer_IO *perIO)
{
	perIO->m_OpType =DISCONNECT_POSTED;
	if (false == lpfnDisconnectEx(perIO->m_hSocket,&perIO->m_Overlapped,mFlag,0))
	{
		int errorCode = GetLastError();
		if (errorCode != WSA_IO_PENDING)
		{
			pObjErrorHanding->ErrorHandlingAndLogging(errorCode,0);
			return ;
		}
	}
}
HPAscySocket::HPAscySocket(void)
{
	GUID GuidDisconnectEx = WSAID_DISCONNECTEX;
	DWORD dwBytes;
	SOCKET tmpSocket ;
	createSocketByTranslateService(AF_INET, SOCK_STREAM, 0, tmpSocket);
	if(SOCKET_ERROR == WSAIoctl(tmpSocket, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidDisconnectEx, sizeof(GuidDisconnectEx),
		&lpfnDisconnectEx, sizeof(lpfnDisconnectEx), &dwBytes, NULL, NULL))
	{
		int errorCode = GetLastError();
		pObjErrorHanding->ErrorHandlingAndLogging(errorCode, 0);
		return ;
	}
	GUID GuidAcceptEx = WSAID_ACCEPTEX;
	if(SOCKET_ERROR == WSAIoctl(
		tmpSocket, 
		SIO_GET_EXTENSION_FUNCTION_POINTER, 
		&GuidAcceptEx, 
		sizeof(GuidAcceptEx), 
		&m_lpfnAcceptEx, 
		sizeof(m_lpfnAcceptEx), 
		&dwBytes, 
		NULL, 
		NULL))  
	{  
		int errorCode = GetLastError();
		if (errorCode != WSA_IO_PENDING)
		{
			pObjErrorHanding->ErrorHandlingAndLogging(errorCode,0);
			return;
		} 
	} 
	pObjErrorHanding = new HPErrorHandling;
	dwBytes = 0;
	mFlag = 0;
}
HPAscySocket::~HPAscySocket(void)
{
	delete pObjErrorHanding;
}
